package cn.imvc.app.models;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.github.sd4324530.fastweixin.api.QrcodeAPI;
import com.github.sd4324530.fastweixin.api.enums.QrcodeType;

import cn.imvc.app.domains.Constants;
import cn.imvc.app.entities.Dealer;
import cn.imvc.app.entities.Domain;
import cn.imvc.app.entities.Member;
import cn.imvc.app.repositories.DealerRepository;
import cn.imvc.data.domain.ViewRequest;
import cn.imvc.util.Wechat;

@Service
public class DealerModelImpl implements DealerModel {

	@Autowired
	Wechat wechat;

	@Autowired
	private DealerRepository dealerRepository;

	@Autowired
	private MemberModel memberModel;

	@Autowired
	private DomainModel domainModel;

	public Dealer get(int id) {
		return dealerRepository.findOne(id);
	}

	public Dealer getByDomain(String domain) {
		return dealerRepository.findByDomain(domain);
	}

	public Page<Dealer> find(ViewRequest viewRequest) {
		return (Page<Dealer>) dealerRepository.findAll();
	}

	public Dealer save(Dealer dealer) {

		Dealer dealer2 = dealerRepository.saveAndFlush(dealer);

		return dealer2;
	}

	public Dealer update(Dealer newDealer) {
		Dealer loadDealer = get(newDealer.getId());
		BeanUtils.copyProperties(newDealer, loadDealer, new String[] { "id" });

		return dealerRepository.saveAndFlush(loadDealer);
	}

	public void delete(int id) {
		dealerRepository.delete(id);

	}

	public void deleteBatch(int[] ids) {

		for (int id : ids) {
			delete(id);
		}

	}
	
	public List<Object[]> getMemberCount(Member member){
		return dealerRepository.findAllSql("SELECT COUNT(id) FROM member WHERE parentId=" + member.getId());
	}
	
	public List<Member> getMember(Member member){
		return dealerRepository.findAllSql("SELECT * FROM member WHERE parentId=" + member.getId(), Member.class);
	}
	
	public List<Object[]> getTeamCount(Member member){
		return dealerRepository.findAllSql("SELECT COUNT(m.id) FROM member m WHERE m.guid LIKE '" + member.getGuid() + ",%'"
				+ " and !(m.guid regexp concat('^',ifnull((SELECT GROUP_CONCAT(m2.id SEPARATOR '|') FROM member m2 INNER JOIN dealer d2"
				+ " ON m2.id=d2.memberId WHERE m2.guid LIKE '" + member.getGuid() + ",%' and d2.dealerLevelId=2),'$')))");
	}
	
	public List<Object[]> getTotalConsumption(Member member){
		return dealerRepository.findAllSql("select sum(n.money) from (SELECT ifnull((SELECT SUM(resultAmount - freightAmount - refundAmount)"
				+ "FROM orders WHERE memberId = m.id AND state >= 60), 0) * 0.01 AS money, '0' money2, m.id, m.`name`, m.loginname, m.guid,	l.`level`"
				+ "FROM member m LEFT JOIN dealer d ON m.id = d.memberId LEFT JOIN dealer_level l ON l.id = d.dealerLevelId"
				+ " WHERE m.guid LIKE '" + member.getGuid() + ",%') n");
	}
	
	public List<Member> getTeam(Member member){
		return dealerRepository.findAllSql("SELECT m.* FROM member m WHERE m.guid LIKE '" + member.getGuid() + ",%'", Member.class);
	}
	
	public List<Object[]> getDealerCount(Member member){
		return dealerRepository.findAllSql("SELECT COUNT(m.id) FROM member m INNER JOIN dealer d ON m.id=d.memberId"
				+ " WHERE m.guid LIKE '%" + member.getGuid() + ",%' and d.dealerLevelId=2");
	}

	public Dealer findByMember(Member member) {
		return dealerRepository.findByMember(member);
	}

	public String updateQrcode(Member member) {
		Dealer dealer = member.getDealer();
		
		if (dealer == null) {
			Domain domain = domainModel.findBymemberId(member.getId());
			return Constants.DOMAIN_PREFIX + (domain == null ? "" : domain.getDomain()) + Constants.DOMAIN_SUFFIX;
		}
	
		
		if (StringUtils.isEmpty(member.getUnionid())) {
			return Constants.DOMAIN_PREFIX + dealer.getDomain() + Constants.DOMAIN_SUFFIX;

		}
					
		if (dealer.getWxqrEndTime() == null || dealer.getWxqrEndTime().getTime() < new Date().getTime()||dealer.getDealerLevel().getType() == 2) {
			dealer.setWxqrEndTime(null);
		}
		if ((dealer.getWxqrEndTime() != null || dealer.getWxqrid() != null) && dealer.getWxqrcode() != null) {
			return dealer.getWxqrcode();
		}

		QrcodeAPI qrcode = new QrcodeAPI(wechat.getApiConfig());

		
		Object object = findMaxWxqrid().get(0);
		Integer maxWxqrid = Integer.parseInt(object.toString());
		
		String url = "";
		if (dealer.getDealerLevel().getType() != 2 || maxWxqrid >= 100000) {
			url = qrcode.createQrcode(QrcodeType.QR_SCENE, (dealer.getId()+100000) + "", 2592000).getUrl();
			Calendar rightNow = Calendar.getInstance();
			rightNow.add(Calendar.DAY_OF_YEAR, 30);
			dealer.setWxqrEndTime(rightNow.getTime());
			dealer.setWxqrcode(url);
			dealer.setUpdatedAt(new Date());
			save(dealer);
		} else {
			url = qrcode.createQrcode(QrcodeType.QR_LIMIT_SCENE, (maxWxqrid + 1) + "", 2592000).getUrl();
			dealer.setWxqrcode(url);
			dealer.setWxqrid(maxWxqrid + 1);
			dealer.setUpdatedAt(new Date());
			save(dealer);
		}

		return url;
	}

	public List<Object[]> findMaxWxqrid() {
		return dealerRepository.findAllSql("select max(case when wxqrid is null then 0 else wxqrid end) from dealer");
	}
	
	public Dealer findByWxqrid(Integer wxqrid){
		return dealerRepository.findByWxqrid(wxqrid);
	}
}
